package org.loofer.ext.utils.security;

import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Digest {
    private static final char[] digits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    private final MessageDigest mDigest;

    public Digest(String algorithm) throws NoSuchAlgorithmException {
        this.mDigest = MessageDigest.getInstance(algorithm);
    }

    public byte[] digest(byte[] source) {
        if (source == null) {
            return null;
        }
        try {
            byte[] digest = this.mDigest.digest(source);
            return digest;
        } finally {
            this.mDigest.reset();
        }
    }

    public String digest(String source) {
        if (source == null) {
            return null;
        }
        return bytes2HexStr(digest(source.getBytes()));
    }

    public String digest(InputStream is) throws IOException {
        if (is == null) {
            return null;
        }
        try {
            byte[] buffer = new byte[1024];
            while (true) {
                int count = is.read(buffer);
                if (count <= 0) {
                    break;
                }
                this.mDigest.update(buffer, 0, count);
            }
            String bytes2HexStr = bytes2HexStr(this.mDigest.digest());
            return bytes2HexStr;
        } finally {
            this.mDigest.reset();
        }
    }

    private static String bytes2HexStr(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        char[] buf = new char[(bytes.length * 2)];
        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];
            buf[(i * 2) + 1] = digits[b & 15];
            buf[i * 2] = digits[((byte) (b >>> 4)) & 15];
        }
        return new String(buf);
    }
}
